﻿using Microsoft.Extensions.DependencyInjection;
using Modules.BankSpecialAccount.Entitys;
using Modules.BankSpecialAccount.Repositories;
using Modules.Common;
using Modules.Payroll.Repositories;
using Pipelines.Sockets.Unofficial.Arenas;
using PmSoft;
using PmSoft.Exceptions;
using static Modules.BankSpecialAccount.BankSpecialAccountConstants;

namespace Modules.BankSpecialAccount
{
    [UseDI(ServiceLifetime.Scoped)]
    public class BankSpecialAccountService
    {
        private readonly BankSpecialAccountRepository projectSpecialAccountRepository;
        private readonly BankSpecialAccountIndexer bankSpecialAccountIndexer;

        public BankSpecialAccountService(BankSpecialAccountRepository projectSpecialAccountRepository,
            BankSpecialAccountIndexer bankSpecialAccountIndexer)
        {
            this.projectSpecialAccountRepository = projectSpecialAccountRepository;
            this.bankSpecialAccountIndexer = bankSpecialAccountIndexer;
        }

        public void CreateProjectSpecialAccount(BankSpecialAccountInfo entity)
        {
            projectSpecialAccountRepository.Insert(entity);
        }

        public int GetProjectSpecialAccountCount(int projectId)
        {
            return projectSpecialAccountRepository.GetProjectSpecialAccountCount(projectId);
        }

        /// <summary>
        /// author:hzj date:2024/2/4 describe:根据流水号获取指定专户数据
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public BankSpecialAccountInfo? GetProjectSpecialAccountByCode(string code)
        {
            return projectSpecialAccountRepository.GetProjectSpecialAccountByCode(code);
        }

        /// <summary>
        /// 根据专户账号获取专户信息
        /// </summary>
        /// <param name="bankAccount"></param>
        /// <returns></returns>
        public BankSpecialAccountInfo? GetProjectSpecialAccountByBankAccount(string bankAccount)
        {
            int? accountId = bankSpecialAccountIndexer.GetId(bankAccount);
            if (accountId.HasValue && accountId > 0)
                return GetProjectSpecialAccount(accountId.Value);
            return null;
        }

        public void DeletProjectSpecialAccounts(IEnumerable<int> ids)
        {
            foreach (int id in ids)
                DeleteProjectSpecialAccount(id);
        }

        public void DeleteProjectSpecialAccount(int id)
        {
            var entity = projectSpecialAccountRepository.Get(id);
            if (entity?.AccountStatus != 专户状态.开户中) throw new BusinessException("专户已经开户无法删除");
            bankSpecialAccountIndexer.Remove(id);//删除索引
            projectSpecialAccountRepository.DeleteByEntityId(id);
        }

        public BankSpecialAccountInfo? GetProjectSpecialAccount(int id)
        {
            return projectSpecialAccountRepository.Get(id);
        }

        public IEnumerable<BankSpecialAccountInfo> GetProjectSpecialAccounts(IEnumerable<int> ids)
        {
            return projectSpecialAccountRepository.PopulateEntitiesByEntityIds(ids);
        }

        public IEnumerable<BankSpecialAccountInfo> GetProjectSpecialAccountByProjectId(int projectId)
        {
            return projectSpecialAccountRepository.GetProjectSpecialAccountByProjectId(projectId);
        }

        /// <summary>
        /// 通过projectId获取正常专户
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public BankSpecialAccountInfo? GetBankSpecialAccountByProjectId(int projectId)
        {
            return projectSpecialAccountRepository.GetBankSpecialAccountByProjectId(projectId);
        }

        public IPagedList<BankSpecialAccountInfo> GetProjectSpecialAccounts(BankSpecialAccountQuery query, int pageIndex, int pageSize)
        {
            return projectSpecialAccountRepository.GetProjectSpecialAccounts(query, pageIndex, pageSize);
        }

        /// <summary>
        /// 银行查询专户专用
        /// </summary>
        /// <param name="query"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IPagedList<BankSpecialAccountInfo> GetReviewBankAccounts(SpecialAccountWithBankQuery query, int pageIndex, int pageSize)
        {
            return projectSpecialAccountRepository.GetReviewBankAccounts(query, pageIndex, pageSize);
        }

        /// <summary>
        /// 获取所有在建项目的正常专户
        /// </summary>
        /// <returns></returns>
        public IEnumerable<BankSpecialAccountInfo> GetAllNormalProjectSpecialAccounts()
        {
            return projectSpecialAccountRepository.GetAllNormalProjectSpecialAccounts();
        }

        public void UpdateProjectSpecialAccount(BankSpecialAccountInfo entity)
        {
            if (entity.ConstructorType == "109010001")
            {
                entity.ConstructorType = "身份证";
            }
            if (entity.LumpContractorCorpType == "109010001")
            {
                entity.LumpContractorCorpType = "身份证";
            }
            projectSpecialAccountRepository.Update(entity);
        }

        public IEnumerable<BankSpecialAccountInfo> GetProjectSpecialAccountByProjectIds(IEnumerable<int> projectIds)
        {
            return projectSpecialAccountRepository.GetProjectSpecialAccountByProjectIds(projectIds);
        }

        /// <summary>
        /// 生成编号和流水号
        /// </summary>
        /// <param name="areaCode"></param>
        /// <returns></returns>
        public (string ProjectNum, int SerialNumber) GetNumAndSerialNumber(string projectNum, int projectId)
        {
            DateTime time = DateTime.Now;
            projectNum = projectNum.Replace(SerialNumberType.项目.GetDescription(), SerialNumberType.工资单.GetDescription());
            BankSpecialAccountInfo? data = projectSpecialAccountRepository.GetProjectSpecialAccountByMaxSerialNumber(time, projectId);
            int SerialNumber = 1;
            //if (data != null)
            //    SerialNumber = data.SerialNumber + 1;
            string ProjectNum = $"{projectNum}-{SerialNumber.ToString().PadLeft(3, '0')}";
            return (ProjectNum, SerialNumber);
        }
    }
}